//
//  NVCustomSegment.m
//  NVCustomSegmentTest
//
//  Created by Yi Lin on 6/18/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>

#import "NVPopoverView.h"

static BOOL _isShown = NO;

@interface NVPopoverView()

@property (strong,nonatomic) UIView *containerView;

@property (strong,nonatomic) UIImageView *arrowImageView;

@property (strong,nonatomic) UIImageView *separatelineView;

- (void)viewGetTapped_:(UITapGestureRecognizer *)gestureRecognizer;

- (void)slideOutPopoverView_:(BOOL)animated;

+ (void)setShown:(BOOL)show;


@end

@implementation NVPopoverView
@synthesize delegate=_delegate;
@synthesize arrowImage=_arrowImage;
@synthesize separatorline=_separatorline;
@synthesize arrowImageView,separatelineView,containerView;
@synthesize componentsView=_componentsView;


+ (NVPopoverView *)sharedPopoverView
{
    static NVPopoverView *gPopoverView = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        gPopoverView = [[NVPopoverView alloc] init];
    });
    return gPopoverView;
}

+ (BOOL)popoverIsShowed
{
    return _isShown;
}

+ (void)setShown:(BOOL)show
{
    @synchronized(self) {
        _isShown = show;   
    }
}

+ (void)dismissPopoverViewAnimated:(BOOL)animate
{
    const UIWindow *keyWin = [UIApplication sharedApplication].keyWindow;
    NSArray *winSubViews = keyWin.subviews;
    
    if([NVPopoverView popoverIsShowed]) {
        
        UIView *theView = nil;
        for (UIView *view in winSubViews) {
            if([view isKindOfClass:[self class]]) {
                theView = view;
                break;
            }
        }
        //not Found
        if(!theView)
            return;
        
        NVPopoverView *popoverView = (NVPopoverView *)theView;
        
        // Found remove
        void (^viewDismissLogic)(BOOL finished) = ^(BOOL finished) {
            [theView removeFromSuperview];
            
            if([popoverView.delegate respondsToSelector:@selector(popoverViewDidDismiss:)]) {
                [popoverView.delegate popoverViewDidDismiss:popoverView];
            }
            
            [NVPopoverView setShown:NO];
        };
        
        
        
        if([popoverView.delegate respondsToSelector:@selector(popoverViewWillDismiss:)]) {
            [popoverView.delegate popoverViewWillDismiss:popoverView];
        }
        
        if(animate) {
            
            
            [UIView animateWithDuration:0.25
                             animations:^{
                                 popoverView.alpha = 0;
                             } completion:viewDismissLogic];
        }
        else {
            viewDismissLogic(YES);
        }
    }
}

+ (void)slideOutPopoverView
{
    const UIWindow *keyWin = [UIApplication sharedApplication].keyWindow;
    NSArray *winSubViews = keyWin.subviews;
    
    if([NVPopoverView popoverIsShowed]) {
        
        UIView *theView = nil;
        for (UIView *view in winSubViews) {
            if([view isKindOfClass:[self class]]) {
                theView = view;
                break;
            }
        }
        //not Found
        if(!theView)
            return;
        
        NVPopoverView *popoverView = (NVPopoverView *)theView;
        
        [popoverView slideOutPopoverView_:YES];
    }
}

#pragma mark - init Methods

- (void)internalInit
{
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                              action:@selector(viewGetTapped_:)];
    tapGesture.numberOfTapsRequired = 1;
    tapGesture.delegate = self;
    self.alpha = 0;
    [self addGestureRecognizer:tapGesture];
    self.backgroundColor = [UIColor colorWithWhite:0.25 alpha:0.5];
    
    self.containerView = [[[UIView alloc] initWithFrame:self.bounds] autorelease];
    
    self.arrowImageView = [[[UIImageView alloc] initWithFrame:CGRectZero] autorelease];
    [self.containerView addSubview:self.arrowImageView];
    self.arrowImageView.hidden = YES;
    
    self.separatelineView = [[[UIImageView alloc] initWithFrame:CGRectZero] autorelease];
    [self.containerView addSubview:self.separatelineView];
    self.separatelineView.hidden = YES;
    
//    self.containerView.layer.borderColor = [UIColor redColor].CGColor;
//    self.containerView.layer.borderWidth = 3;
    [self addSubview:self.containerView];
    
    self.clipsToBounds = YES;
}

- (id)init 
{
    if(self = [super init]) {
        [self internalInit];
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    if(self = [super initWithFrame:frame]) {
        [self internalInit];        
    }
    return self;
}

#pragma mark - Properties
- (void)setArrowImage:(UIImage *)theImage
{
    if(_arrowImage != theImage) {
        _arrowImage=theImage;
        self.arrowImageView.image = theImage;
        
        if(theImage) {
            self.arrowImageView.bounds = CGRectMake(0, 0,
                                                    theImage.size.width,
                                                    theImage.size.height);
            self.arrowImageView.hidden = NO;
        }
        else {
            self.arrowImageView.hidden = YES;
        }
    }
}

- (void)setSeparatorline:(UIImage *)theImage
{
    if(_separatorline != theImage) {
        _separatorline=theImage;
        self.separatelineView.image = theImage;
        
        if(theImage) {
            self.separatelineView.bounds = CGRectMake(0, 0,
                                                    theImage.size.width,
                                                    theImage.size.height);
            self.separatelineView.hidden = NO;
        }
        else {
            self.separatelineView.hidden = YES;
        }
    }
}

- (void)setComponentsView:(UIView *)theView 
{
    if(theView!= _componentsView) {
        [_componentsView removeFromSuperview];
        _componentsView = theView;

        [self.containerView addSubview:_componentsView];

        CGRect containerBounds = _componentsView?_componentsView.bounds:CGRectZero;
        
        self.containerView.frame = containerBounds;
    }
}

#pragma mark - Layouts Views
- (void)layoutSubviews
{
    [super layoutSubviews];
    
    CGRect rect = self.componentsView.frame;
    rect.origin.x = 15;
    rect.origin.y = 0;
    rect.size.width = 290;
    rect.size.height = 280;
    self.componentsView.frame = rect;
    
    if(self.componentsView) {        
        self.containerView.frame = self.componentsView.bounds;
    }
   
    
    if(!self.arrowImageView.hidden) {
        CGRect newFrame = CGRectOffset(self.containerView.frame,0,0.5*self.arrowImageView.bounds.size.height);        
        self.containerView.frame = newFrame;
    }
}

#pragma mark - Actions & out interface

- (void)showPopoverViewInView:(UIView *)targetView position:(NVPopoverPosition)thePosition animated:(BOOL)animate
{
    CGRect selfBounds = [UIScreen mainScreen].bounds;
    CGRect targetViewFrameInScreen = [targetView.superview convertRect:targetView.frame toView:nil];
    
    if(CGRectIsNull(targetViewFrameInScreen) || CGRectIsEmpty(targetViewFrameInScreen))
        targetViewFrameInScreen = targetView.frame;
    
    if(thePosition == NVPopoverPositionBelow) {
        const CGFloat yOffset = (targetViewFrameInScreen.origin.y + targetViewFrameInScreen.size.height);
        selfBounds.size.height -= (yOffset-1);
        selfBounds.origin.y = yOffset -1;
        self.alpha = 1;
        //draw arrowImage
        if(!self.arrowImageView.hidden) {
            self.arrowImageView.center = CGPointMake(CGRectGetMidX(targetViewFrameInScreen),
                                                     -CGRectGetMidY(self.arrowImageView.bounds));
            
            self.separatelineView.center = CGPointMake(self.center.x,-1);
            if([self.arrowImageView superview] != self.containerView)
                [self.containerView addSubview:arrowImageView];
            
            if([self.separatelineView superview] != self.containerView) 
                [self.containerView addSubview:separatelineView];
        }

    }
    else if(thePosition == NVPopoverPositionAbove) {
        
    }
    else if(thePosition == NVPopoverPositionLeft) {
        
    }
    else if(thePosition == NVPopoverPositionRight) {
        
    }
    else if(thePosition == NVPopoverPositionCenter) {
        
    }
    else if(thePosition == NVPopoverPositionAny) {

    }
    
    self.frame = selfBounds;
    const UIWindow *keyWin = [AppDelegate instance].window;
    
    if(!self.arrowImageView.hidden) {
        
        if(self.componentsView) {        
            self.containerView.frame = self.componentsView.bounds;
        }
        
        CGRect newContainerFrame = CGRectOffset(self.containerView.frame,0,0.5*self.arrowImageView.bounds.size.height);
        self.containerView.frame = newContainerFrame;
    }
    
    //only allow one instance in front of the win
    NSArray *winSubViews = keyWin.subviews;
    UIView *theView = [winSubViews lastObject];
    if([theView isKindOfClass:[self class]]) {
        [NVPopoverView dismissPopoverViewAnimated:NO];
    }
    
    //add new popover view
    [keyWin addSubview:self];
    [NVPopoverView setShown:YES];
        
    void (^appearDelegateCallback)(BOOL finished) = ^(BOOL finished) {
        //delegate callback
        if([self.delegate respondsToSelector:@selector(popoverViewDidAppear:)]) {
            [self.delegate popoverViewDidAppear:self];
        }
    };
    
    if([self.delegate respondsToSelector:@selector(popoverViewWillAppear:)]) {
        [self.delegate popoverViewWillAppear:self];
    }
    
    if(animate) {
        
        const CGPoint componentOriginCenter = self.containerView.center;
        CGPoint targetCenter = componentOriginCenter;
        targetCenter.y -= targetViewFrameInScreen.size.height;
        targetCenter.y -= self.containerView.bounds.size.height;
        
        self.containerView.center = targetCenter;
        
        [UIView animateWithDuration:0.5
                              delay:0
                            options:UIViewAnimationCurveEaseInOut
                         animations:^{
                             self.containerView.center = componentOriginCenter;
                         } completion:appearDelegateCallback];

    }
    else {
        appearDelegateCallback(YES);
    }

}

- (void)removeAllSubviews
{
    NSArray *array = self.subviews;
    for(UIView *theView in array) {
        [theView removeFromSuperview];
    }
}



- (void)viewGetTapped_:(UITapGestureRecognizer *)gestureRecognizer
{
     if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
         
         [NVPopoverView dismissPopoverViewAnimated:YES];
     }
}

- (void)slideOutPopoverView_:(BOOL)animated
{
    // Found remove
    void (^completion)(BOOL finished) = ^(BOOL finished) {
        [self removeFromSuperview];
        
        if([self.delegate respondsToSelector:@selector(popoverViewDidDismiss:)]) {
            [self.delegate popoverViewDidDismiss:self];
        }
        
        [NVPopoverView setShown:NO];
    };
    
    if([self.delegate respondsToSelector:@selector(popoverViewWillDismiss:)]) {
        [self.delegate popoverViewWillDismiss:self];
    }
    if(animated) {
    
        CGPoint containerCenter = self.containerView.center;
        containerCenter.y = -2.5*containerCenter.y;
        
        [UIView animateWithDuration:0.5
                              delay:0
                            options:UIViewAnimationCurveEaseInOut
                         animations:^{
                             self.containerView.center = containerCenter;
                         } completion:completion];
    }
    else {
        completion(YES);
    }
}


- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if (gestureRecognizer.view != touch.view) {
        return NO;
    }
    return YES;
}

- (void)dealloc
{
    self.delegate = nil;
    [super dealloc];
}

@end
